﻿using System;
using System.Collections.Generic;
using System.Xml;
using IURIP;
using URIP.Tool;

namespace URIP.Core
{
    public class Target : ITarget
    {
        public Target(ITask task)
        {
            m_task = task;
        }

        private string m_name = "";
        private bool m_isSingle = false;
        private bool m_isDependent = true;
        private ITask m_task = null;
        private Dictionary<string, IDataBlock> m_dataBlocks = new Dictionary<string, IDataBlock>();
        private IMap m_map = null;
        private IProcessTemplate m_processTemplate = null;

        public string Name
        {
            get { return m_name; }
        }
        public bool IsSingle
        {
            get { return m_isSingle; }
        }
        public bool IsDependent
        {
            get { return m_isDependent; }
        }
        public ITask Task
        {
            get { return m_task; }
        }
        public Dictionary<string, IDataBlock> DataBlocks
        {
            get { return m_dataBlocks; }
        }
        public IMap Map
        {
            get { return m_map; }
        }
        public IProcessTemplate ProcessTemplate
        {
            get { return m_processTemplate; }
        }

        public void InitByConfiguration(XmlNode node)
        {
            this.m_name = Util.GetAttributeValue(node, "name");
            if (string.IsNullOrEmpty(m_name))
            {
                throw new Exception(string.Format("There is a target has no valid name. All targets should have unique name."));
            }
            this.m_isSingle = Util.GetAttributeBoolValue(node, "isSingle", false);
            this.m_isDependent = Util.GetAttributeBoolValue(node, "isDependent", true);

            this.InitDataBlocks(node);
            this.InitMap(node);
            this.InitProcessTemplate(node);
        }

        private void InitDataBlocks(XmlNode node)
        {
            XmlNodeList dataBlockList = node.SelectNodes("./dataBlocks/dataBlock");
            Task.Logger.LogDebug("Start loading DataBlocks for target '{0}'. Quantity of defined data blocks is {1}.", Name, dataBlockList.Count);
            for (int i = 0; i < dataBlockList.Count; i++)
            {
                IDataBlock dataBlock = new DataBlock(this);
                dataBlock.InitByConfiguration(dataBlockList[i]);
                if (DataBlocks.ContainsKey(dataBlock.Name))
                {
                    throw new Exception(string.Format("There are many Datablocks for target '{0}' have the same name '{1}'.", Name, dataBlock.Name));
                }
                DataBlocks.Add(dataBlock.Name, dataBlock);
                Task.Logger.LogInfo("Finish loading DataBlock '{0}'.", dataBlock.Name);
            }
            Task.Logger.LogDebug("Finish loading DataBlocks for target '{0}'. Quantity of loaded data blocks is {1}.", Name, DataBlocks.Count);
        }
        private void InitMap(XmlNode node)
        {
            m_map = new Map(this);
            XmlNode mapNode = node.SelectSingleNode("./map");
            if (mapNode != null)
            {
                Task.Logger.LogDebug("Start loading map for target '{0}'.", Name);
                m_map.InitByConfiguration(mapNode);
                Task.Logger.LogDebug("Finish loading map for target '{0}'.", Name);
            }
            else
            {
                Task.Logger.LogWarning("There is no map defined for target '{0}'!", Name);
            }
        }
        private void InitProcessTemplate(XmlNode node)
        {
            m_processTemplate = new ProcessTemplate(this, null);
            XmlNode processTemplateNode = node.SelectSingleNode("./process");
            if (processTemplateNode != null)
            {
                Task.Logger.LogDebug("Start loading process template for target '{0}'.", Name);
                m_processTemplate.InitByConfiguration(processTemplateNode);
                Task.Logger.LogDebug("Finish loading process template for target '{0}'.", Name);
            }
            else
            {
                Task.Logger.LogWarning("There is no process template defined for target '{0}'!", Name);
            }
        }
    }
}
